<?php
/**
 * 分页类
 * 
 * [Code]
 * $c = App::C('Pagination', null, $page, $totalPage, 8, array('first'=>'首页','pre'=>'上一页','next'=>'下一页','last'=>'尾页'));
 * $pagination = $c->display();
 * [/Code]
 * 
 * @version $Id: Pagination.php 418 2013-01-30 07:22:01Z linsir123 $
 * @package Component
 */
class comPagination
{
	/**
	 * 链接中页码的替换关键字
	 */
	const URL_P = "__PAGE__";
	
	/**
	 * 链接中描述的替换关键字
	 */
	const URL_TERM = "__TERM__";
	
	/**
	 * @var 链接中页码的样式
	 */
	public $urlPStyle = 0;
	
	/**
	 * @var 分页的链接格式(需要预留%d以供填充)
	 */
	public $url;
	
	/**
	 * @var 当前页码
	 */
	public $pageId;
	
	/**
	 * @var 总页数
	 */
	public $pageCount;
	
	/**
	 * @var 显示的分页个数
	 */
	public $pageShow;
	
	/**
	 * @var 显示的分页文案
	 */
	public $terms;
	
	/**
	 * @var 链接HTML格式化
	 */
	public $aFormat;
	
	/**
	 * 构造函数
	 * 
	 * @param string $url 分页的链接格式(需要预留%d以供填充)
	 * @param int $pageId 当前页码
	 * @param int $pageCount 总页数
	 * @param int $pageShow 显示的分页个数
	 * @param array $terms 显示的分页文案
	 */
	public function __construct($url, $pageId, $pageCount, $pageShow = 10, $terms = array())
	{
		if ($pageId < 1) 
			$pageId = 1;
		elseif ($pageId > $pageCount) 
			$pageId = $pageCount;
			
		if (empty($terms)) 
			$terms = array(
				'first' => '首页',
				'pre' => '上一页',
				'next' => '下一页',
				'last' => '尾页'
			);
			
		///
		$this->url = $url;
		$this->pageId = $pageId;
		$this->pageCount = $pageCount;
		$this->pageShow = $pageShow;
		$this->terms = $terms;
	}
	
	/**
	 * 自定义HTML格式化
	 * 
	 * @param string $format
	 */
	public function setAformat($format)
	{
		$this->aFormat = $format;
	}
	
	/**
	 * 自定义链接中页码的替换方式
	 * 
	 * @param int $style 0以%d方式; 1以字符方式进行替换
	 */
	public function setUrlPStyle($style = 0)
	{
		$this->urlPStyle = $style;
	}
	
	/**
	 * 取得分类数据,用于html的自定义
	 */
	public function getData()
	{
		if ($this->pageCount <= 1) 
			return false;
			
		$data = array(
			'first'=>null,
			'pre'=>null,
			'num'=>array(
				'pre'=>false,
				'list'=>array(),
				'next'=>false
			),
			'next'=>null,
			'last'=>null,
		);
		list($startPage, $endPage) = $this->_getRange();
		
		///
		if ($this->pageId > 1) {
			$data['first'] = sprintf($this->url, 1);
			$data['pre'] = sprintf($this->url, $this->pageId - 1);
		}
		$data['num']['pre'] = $startPage >= 2 && $this->pageShow < $this->pageCount;
		for ($i = $startPage; $i <= $endPage; $i++) {
			if ($i == $this->pageId) 
				$data['num']['list'][$i] = array($i);
			else
				$data['num']['list'][$i] = sprintf($this->url, $i);
		}
		$data['num']['next'] = $endPage < $this->pageCount;
		if ($this->pageId < $this->pageCount) {
			$data['next'] = sprintf($this->url, $this->pageId + 1);
			$data['last'] = sprintf($this->url, $this->pageCount);
		}
		
		return $data;
	}
	
	/**
	 * 以分页，显示分页内容
	 */
	public function display()
	{
		if ($this->pageCount <= 1) 
			return false;
			
		$nav = '';
		list($startPage, $endPage) = $this->_getRange();
		
		///
		if ($this->pageId > 1) {
			if (isset($this->terms['first'])) 
				$nav .= $this->_a(1, $this->terms['first']);
				
			$nav .= $this->_a($this->pageId - 1, $this->terms['pre']);
		}
		if ($startPage >= 2 && $this->pageShow < $this->pageCount) 
			$nav .= "<span>...</span>";
			
		///
		for ($i = $startPage; $i <= $endPage; $i++) {
			if ($i == $this->pageId) 
				$nav .= "<span class=\"current\">$i</span>";
			else
				$nav .= $this->_a($i, $i);
		}
		
		///
		if ($endPage < $this->pageCount) 
			$nav .= "<span>...</span>";
			
		if ($this->pageId < $this->pageCount) {
			$nav .= $this->_a($this->pageId + 1, $this->terms['next']);
			if (isset($this->terms['last'])) 
				$nav .= $this->_a($this->pageCount, $this->terms['last']);
		}
		
		return "<div id=\"page_nav\">{$nav}</div>";
	}
	
	
	/// 以下为私有方法 ///
	
	
	/**
	 * 取得区间上下限
	 */
	private function _getRange()
	{
		$pageShow2 = $this->pageShow - 1;
		$halfStart = floor($pageShow2 / 2);
		$halfEnd = ceil($pageShow2 / 2);
		$startPage = $this->pageId - $halfStart;
		$endPage = $this->pageId + $halfEnd;
		
		///
		if ($startPage <= 0) 
			$startPage = 1;
			
		if (($endPage - $startPage) != $pageShow2) 
			$endPage = $startPage + $pageShow2;
			
		if ($endPage > $this->pageCount) {
			$startPage = $this->pageCount - $pageShow2;
			$endPage = $this->pageCount;
		}
		
		if ($startPage <= 0) 
			$startPage = 1;
			
		return array($startPage, $endPage);
	}
	
	/**
	 * 格式化链接HTML
	 * 
	 * @param int $pageId 页码
	 * @param string $term 显示内容
	 * @return string
	 */
	private function _a($pageId, $term)
	{
		if (empty($this->aFormat)) 
			$dom = "<a href=\"". $this->url ."\">". ($this->urlPStyle==0?"%s":self::URL_TERM) ."</a>";
		else 
			$dom = $this->aFormat;
			
		///
		if ($this->urlPStyle == 0) 
			return sprintf($dom, $pageId, $term);
			
		///
		$dom = str_replace(self::URL_TERM, $term, $dom);
		$dom = str_replace(self::URL_P, $pageId, $dom);
		return $dom;
	}
}
